 /*
 * UMLSynch - VPSDE plugin part
 * http://umlsynch.googlecode.com
 *
 * Copyright 2008-2010, Evgeny Alexeyev
 * Licensed under the EPL - v1.0
 * http://www.eclipse.org/legal/epl-v10.html
 *
 */

package com.googlecode.umlsynch.vpsde.plugins.menuitem.search;


import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Iterator;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextPane;
import javax.swing.JViewport;

import sun.awt.windows.WEmbeddedFrame;

import com.googlecode.umlsynch.vpsde.rpc.VPSDEDiagramManager.VPClassDiagramManager;
import com.googlecode.umlsynch.vpsde.rpc.VPSDEDiagramManager.VPPackageDiagramManager;
import com.googlecode.umlsynch.vpsde.rpc.VPSDEDiagramManager.VPPropertyManager;
import com.googlecode.umlsynch.vpsde.rpc_old.EclipseOperationServer.IEclipseOperationServer;
import com.googlecode.umlsynch.vpsde.rpc_old.EclipseOperationServer.TEclipseOperationServerCaller;
import com.googlecode.umlsynch.vpsde.rpc_old.EclipseOperationServer.VPSDESearchQueryDescription;
import com.googlecode.umlsynch.vpsde.rpc_old.EclipseOperationServer.VPSDESearchQueryDescription.TSearchType;
import com.vp.plugin.ApplicationManager;
import com.vp.plugin.ViewManager;
import com.vp.plugin.action.VPAction;
import com.vp.plugin.action.VPContext;
import com.vp.plugin.action.VPContextActionController;
import com.vp.plugin.diagram.IDiagramElement;
import com.vp.plugin.diagram.IDiagramUIModel;
import com.vp.plugin.diagram.IShapeUIModel;
import com.vp.plugin.diagram.shape.IClassUIModel;
import com.vp.plugin.model.IClass;
import com.vp.plugin.model.IModelElement;
import com.vp.plugin.model.IPackage;
import com.vp.plugin.model.ISimpleRelationship;

public class ActionController implements VPContextActionController {
	
	private IEclipseOperationServer eclop = TEclipseOperationServerCaller.instance();
	
	private Integer indent = 0;
	private Integer counter = 0;
	private Integer counter2 = 0;
	
	class TestML implements MouseListener {
		private Integer intc = new Integer(counter++);
		@Override
		public void mouseClicked(MouseEvent arg0) {
			ApplicationManager.instance().getViewManager().showMessage("mc" + intc);
		}

		@Override
		public void mouseEntered(MouseEvent arg0) {
			ApplicationManager.instance().getViewManager().showMessage("c" + intc);
		}
		public void mouseExited(MouseEvent arg0) {
		}
		@Override
		public void mousePressed(MouseEvent arg0) {
			ApplicationManager.instance().getViewManager().showMessage("p" + intc);
		}

		@Override
		public void mouseReleased(MouseEvent arg0) {
		}
	};

	private void ShowBounds(String prefix, Rectangle bds)
	{
		ViewManager vm = ApplicationManager.instance().getViewManager();
		vm.showMessage(prefix + ": x=" + bds.x + "  y="  + bds.y +
				" w=" + bds.width + " h=" + bds.height);

	}
	
	private void RecursiveOutput(Component comp) {

		Component[] components = null;
		ViewManager vm = ApplicationManager.instance().getViewManager();
		String ind = "Comp:"; 
		for (int g=0; g<indent; ++g) {
			ind += "  ";
		}

		try {
			vm.showMessage(ind +comp.getClass().getName() + " : "+ comp.getName());	

			if (comp != null) {
				vm.showMessage("Reg Mouse listener #" + counter);
				comp.addMouseListener(new TestML());
				ShowBounds("comp", comp.getBounds());
			}
			
		if (comp instanceof Window) {
			Window w = (Window)comp;
			components = w.getComponents();
		} else if (comp instanceof JFrame) {
			JFrame w = (JFrame)comp;
			components = w.getComponents();
		} else if (comp instanceof JRootPane) {
			JRootPane rp = (JRootPane)comp;
			components = rp.getContentPane().getComponents();
			
			rp.getGlassPane().addMouseListener(new TestML());
//			ShowBounds("GlassPane", rp.getGlassPane().getBounds());
			rp.getLayeredPane().addMouseListener(new TestML());
//			ShowBounds("LayerdPane", rp.getLayeredPane().getBounds());
		} else if (comp instanceof JScrollPane) {
			JScrollPane rp = (JScrollPane)comp;
			components = rp.getComponents();
			
		} else if (comp instanceof JSplitPane) {
			JSplitPane rp = (JSplitPane)comp;
			++indent;
//			vm.showMessage("Left");
			RecursiveOutput(rp.getLeftComponent());
//			vm.showMessage("Right");
			RecursiveOutput(rp.getRightComponent());
			--indent;
//			vm.showMessage("All");
//			components = rp.getComponents();
		} else if (comp instanceof JLayeredPane) {
			JLayeredPane rp = (JLayeredPane)comp;
			components = rp.getComponents();
		} else if (comp instanceof JPanel) {
			JPanel rp = (JPanel)comp;
			components = rp.getComponents();
		} else if (comp instanceof Panel) {
			Panel p = (Panel)comp;
			components = p.getComponents();
		} else if (comp instanceof JTextPane) {
//			vm.showMessage("JTextPane");
		}else if (comp instanceof JLabel) {
//			vm.showMessage("JTextLabel");
		}else if (comp instanceof JViewport) {
			JViewport rp = (JViewport)comp;
			class MyDTL implements DropTargetListener {
				private Integer cc = new Integer(counter2++);
				@Override
				public void dragEnter(DropTargetDragEvent arg0) {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void dragExit(DropTargetEvent arg0) {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void dragOver(DropTargetDragEvent arg0) {
					// TODO Auto-generated method stub
					
				}

				private void print(String str) {
					ApplicationManager.instance().getViewManager()
					.showMessage(str);
				}
				
				@Override
				public void drop(DropTargetDropEvent arg0) {
					Transferable tr = arg0.getTransferable();
					
					DataFlavor[] flows = tr.getTransferDataFlavors();
					for (int f=0; f<flows.length; f++) {
						print("Mime type " + f + "  " + flows[f].getMimeType() + "  "
							+ flows[f].getHumanPresentableName());						
					}
					print("-------------------------- DROPED" + cc + "----------------------");
					
					arg0.rejectDrop();
					
				}

				@Override
				public void dropActionChanged(DropTargetDragEvent arg0) {
					// TODO Auto-generated method stub
					
				}};
     			components = rp.getComponents();
     			for (int t=0; t < components.length; ++t) {
     				if (components[t].getClass().getName() == "v.iezc") {
     					components[t].setDropTarget(new DropTarget(components[t], new MyDTL()) {});     					
     				}
     			}
     			
		} else {
			vm.showMessage("Unknown container type");
			comp.getGraphics().setColor(Color.yellow);
			comp.paint(comp.getGraphics());
			comp.getGraphics().drawRect(0, 0, 20, 20);
			
			if (comp.getAccessibleContext() != null) {
				int ccc = comp.getAccessibleContext().getAccessibleChildrenCount();
				vm.showMessage("Acc child count: " + ccc); 
						
				for (int v=0; v<ccc; ++v) {
					vm.showMessage("chclnam:" + comp.getAccessibleContext().getAccessibleChild(v).getClass().getSimpleName());
					if (comp.getAccessibleContext().getAccessibleChild(v) instanceof Component) {
						vm.showMessage("IT IS COMPONENT");
						++indent;
						RecursiveOutput((Component)comp.getAccessibleContext().getAccessibleChild(v) );
						--indent;
					}
					
				}
				
				if (comp.getAccessibleContext().getAccessibleComponent() instanceof Component) {
					vm.showMessage("ACCCOMPONENT is COMP");
					++indent;
					RecursiveOutput((Component)comp.getAccessibleContext().getAccessibleComponent());
					--indent;
				}
			}
		}
		++indent;
		for (int t=0; (components != null) && (t<components.length); ++t){
			RecursiveOutput(components[t]);
		}
		--indent;
		} catch (Exception ex) {
			vm.showMessage("exception" + ex.getLocalizedMessage());
		}
	}
	
	@Override
	public void performAction(VPAction action, VPContext context, ActionEvent event) {
		// Analyze the component diagram action
		ApplicationManager.instance().getViewManager().showMessage("Event ID= " + action.getActionId());
		
		IDiagramElement[] selectedElements = context.getDiagram().getSelectedDiagramElement();
		IDiagramElement selectedElement = context.getDiagramElement();
		IModelElement modEl = context.getModelElement();
		IDiagramUIModel diagram = context.getDiagram();
		
		VPSDESearchQueryDescription desc = new VPSDESearchQueryDescription();
		
		ApplicationManager.instance().getViewManager().showMessage("Searching: " + selectedElement.getMetaModelElement().getName());
		
		desc.projectName = ApplicationManager.instance().getProjectManager().getProject().getName();
		desc.fSearchDerived = true;
		desc.isCaseSensitive = false;
		desc.isRegExSearch = false;
		desc.SearchPatterns = new String[1];
		desc.SearchPatterns[0] = "*";
		desc.SearchPaths = new String[1];
		desc.SearchPaths[0] = desc.projectName + "/"; 
			//VPClassDiagramManager.instance().
		    //	GetClasPropery(selectedElements[1].getModelElement(), VPClassDiagramManager.PROP_CLASS_FILE_NAME);

		ViewManager vm = ApplicationManager.instance().getViewManager();
		Component rootFrame = vm.getRootFrame();
		
		if (rootFrame instanceof WEmbeddedFrame) {
			WEmbeddedFrame embf = (WEmbeddedFrame)rootFrame;
			Frame[] fms = embf.getFrames();
			Window[] ws = embf.getWindows();
			for (int fr=0; fr<ws.length; fr++){
				RecursiveOutput(ws[fr]);
			}
		}

		desc.searchText = ApplicationManager.instance().getViewManager().showInputDialog(null, "Searching:", modEl.getName());

		if ((desc.searchText == null) || (desc.searchText.isEmpty())) {
			return;
		}
		
		
		ApplicationManager.instance().getViewManager().showMessage("Searching: 2");
		desc.SearchType = TSearchType.SELECTED_PROJECTS_SCOPE;
		
		if (action.getActionId().equals("com.googlecode.umlsynch.vpsde.plugins.menuitem.popup_menu_component_actionset.Search.InComponent")) {
			desc.SearchType = TSearchType.SELECTION_SCOPE;
			
			if (diagram.getParentModel() != null) {
				ApplicationManager.instance().getViewManager()				
				.showMessage("Parrent " + diagram.getParentModel().getName());
				IModelElement elt = diagram.getParentModel();
				if (elt instanceof IPackage) {
					   desc.SearchPaths = new String[1];
					   desc.SearchPaths[0] = 
						   VPPropertyManager.instance().GetProperty(elt, VPPackageDiagramManager.PACKAGE_PATH);
				} else  if (elt instanceof IClass) {
					   desc.SearchPaths = new String[1];
					   desc.SearchPaths[0] = 
						   VPPropertyManager.instance().GetProperty(elt, VPClassDiagramManager.PROP_CLASS_FILE_NAME);
				} else {
					ApplicationManager.instance().getViewManager()				
					.showMessage("Unknow parrent element");
					return;
				}
				
				if (desc.SearchPaths[0] == null) {
					ApplicationManager.instance().getViewManager()				
					.showMessage("Empty properties in parrent element");
					return;
				}				
			}
			
			ApplicationManager.instance().getViewManager()				
			.showMessage("In Package:" + desc.SearchPaths[0]);
		} else if (action.getActionId().equals("com.googlecode.umlsynch.vpsde.plugins.menuitem.popup_menu_component_actionset.Search.InComponentDep")) {
			desc.SearchType = TSearchType.SELECTION_SCOPE;
			if (diagram.getParentModel() != null) {
				IModelElement elt = diagram.getParentModel();
				ApplicationManager.instance().getViewManager()				
				.showMessage("Parrent " + diagram.getParentModel().getName());
				
				if (elt instanceof IPackage) {
					IPackage pack = (IPackage)elt;
					ApplicationManager.instance().getViewManager()				
					.showMessage("Parrent IPackage " + pack.fromRelationshipCount() + 
					"  RefCount " + pack.referenceCount() + " toRelationshipCount " + pack.toRelationshipCount() );
					
					ISimpleRelationship[] relArr = pack.toFromRelationshipArray();

					for (int i=0; i<relArr.length; ++i ) {
						ApplicationManager.instance().getViewManager()				
						.showMessage(" SimpleRelation: " + 					
						relArr[i].getTo().getName());
					}
					
				}
				desc.SearchPaths = new String[1];
				desc.SearchPaths[0] = VPClassDiagramManager.instance().
				    	GetClasPropery(selectedElements[1].getModelElement(), VPClassDiagramManager.PROP_CLASS_FILE_NAME);
			}
			ApplicationManager.instance().getViewManager()				
			.showMessage("In Package Dependency");
		} else if (action.getActionId().equals("com.googlecode.umlsynch.vpsde.plugins.menuitem.popup_menu_component_actionset.Search.InSelection")) {
			
			if (selectedElement instanceof  IClassUIModel) {
				IClassUIModel uiClass = (IClassUIModel) selectedElement;
				IClass modelEl = (IClass) uiClass.getModelElement();

				ApplicationManager.instance().getViewManager()				
				.showMessage("Instance of IClassUIModel");						

				
				Iterator iter = uiClass.childIterator();
				while (iter.hasNext()) {
					IShapeUIModel child = (IShapeUIModel) iter.next();
					IModelElement mm = child.getModelElement();
					if (mm != null) {
						ApplicationManager.instance().getViewManager()				
						.showMessage("Model element " + mm.getName());						
					} else {
						ApplicationManager.instance().getViewManager()				
						.showMessage("Meta-Model element null");						
					}
					
				}
			}
			
			desc.SearchType = TSearchType.SELECTION_SCOPE;
			desc.SearchPaths = new String[selectedElements.length];
			for (int i=0; i<selectedElements.length; ++i) {
				desc.SearchPaths[i] = VPClassDiagramManager.instance().
			    	GetClasPropery(selectedElements[i].getModelElement(), VPClassDiagramManager.PROP_CLASS_FILE_NAME);
			}

			ApplicationManager.instance().getViewManager()				
			.showMessage("In selection:");
		} else if (action.getActionId().equals("com.googlecode.umlsynch.vpsde.plugins.menuitem.popup_menu_component_actionset.Search.InProject")) {
			desc.SearchType = TSearchType.SELECTED_PROJECTS_SCOPE;
			ApplicationManager.instance().getViewManager()				
			.showMessage("In Project:");
		} else if (action.getActionId().equals("com.googlecode.umlsynch.vpsde.plugins.menuitem.popup_menu_component_actionset.Search.InWorkspace")) {
			desc.SearchType = TSearchType.WORKSPACE_SCOPE;
			ApplicationManager.instance().getViewManager()				
			.showMessage("In Workspace");
		}
		eclop.SearchTextPattern(desc);
	}
			
	@Override
	public void update(VPAction arg0, VPContext arg1) {
	}
}
